import random
# 正则校验的包
import re
import base64
import constants as c


# 初始化一个新的游戏矩阵
def new_game(n):
    matrix = []
    for i in range(n):
        matrix.append([0] * n)  # 创建n×n的零矩阵
    matrix = add_two(matrix)  # 添加两个初始数字2
    matrix = add_two(matrix)
    return matrix


# 在随机空白位置添加数字2
def add_two(mat):
    a = random.randint(0, len(mat) - 1)
    b = random.randint(0, len(mat) - 1)
    while mat[a][b] != 0:  # 确保选择的是空白位置
        a = random.randint(0, len(mat) - 1)
        b = random.randint(0, len(mat) - 1)
    mat[a][b] = 2
    return mat


# 检查游戏状态: 赢/继续/输
def game_state(mat):
    # 检查是否有2048
    for i in range(len(mat)):
        for j in range(len(mat[0])):
            if mat[i][j] == 2048:
                return 'win'

    # 检查是否有空格
    for i in range(len(mat)):
        for j in range(len(mat[0])):
            if mat[i][j] == 0:
                return 'not over'

    # 检查相邻是否有相同数字(可合并)
    for i in range(len(mat) - 1):
        for j in range(len(mat[0]) - 1):
            if mat[i][j] == mat[i + 1][j] or mat[i][j + 1] == mat[i][j]:
                return 'not over'

    # 检查最后一行左右相邻
    for k in range(len(mat) - 1):
        if mat[len(mat) - 1][k] == mat[len(mat) - 1][k + 1]:
            return 'not over'

    # 检查最后一列上下相邻
    for j in range(len(mat) - 1):
        if mat[j][len(mat) - 1] == mat[j + 1][len(mat) - 1]:
            return 'not over'

    # 以上条件都不满足，游戏失败
    return 'lose'


# 水平翻转矩阵
def reverse(mat):
    new = []
    for i in range(len(mat)):
        new.append([])
        for j in range(len(mat[0])):
            # 将每行元素逆序排列
            new[i].append(mat[i][len(mat[0]) - j - 1])
    return new


# 矩阵转置
def transpose(mat):
    new = []
    for i in range(len(mat[0])):
        new.append([])
        for j in range(len(mat)):
            # 行列互换
            new[i].append(mat[j][i])
    return new


# 将非零元素向左移动，压缩矩阵
def cover_up(mat):
    new = []
    # 初始化新矩阵
    for j in range(c.GRID_LEN):
        partial_new = []
        for i in range(c.GRID_LEN):
            partial_new.append(0)
        new.append(partial_new)

    done = False
    for i in range(c.GRID_LEN):
        count = 0
        for j in range(c.GRID_LEN):
            if mat[i][j] != 0:
                # 将非零元素移到左侧
                new[i][count] = mat[i][j]
                if j != count:  # 如果有移动发生
                    done = True
                count += 1
    return new, done


# def get_score:

def merge(mat, done):
    for i in range(c.GRID_LEN):
        for j in range(c.GRID_LEN - 1):
            if mat[i][j] == mat[i][j + 1] and mat[i][j] != 0:
                # 合并相同数字
                mat[i][j] *= 2
                mat[i][j + 1] = 0
                done = True  # 标记有合并发生
    return mat, done


def up(game):
    # print("up")
    # 转置后向左移动相当于原矩阵向上移动
    game = transpose(game)
    game, done = cover_up(game)  # 压缩
    game, done = merge(game, done)  # 合并
    game = cover_up(game)[0]  # 再次压缩
    game = transpose(game)  # 转置回来
    return game, done


def down(game):
    # print("down")
    # 转置+翻转后向左移动相当于原矩阵向下移动
    game = reverse(transpose(game))
    game, done = cover_up(game)
    game, done = merge(game, done)
    game = cover_up(game)[0]
    game = transpose(reverse(game))  # 翻转+转置回来
    return game, done


def left(game):
    # print("left")
    # 直接处理左移
    game, done = cover_up(game)
    game, done = merge(game, done)
    game = cover_up(game)[0]
    return game, done


def right(game):
    # print("right")
    # 翻转后左移相当于原矩阵右移
    game = reverse(game)
    game, done = cover_up(game)
    game, done = merge(game, done)
    game = cover_up(game)[0]
    game = reverse(game)  # 翻转回来
    return game, done


def check_string_length(str):
    pattern = r'^.{1,7}$'
    return bool(re.fullmatch(pattern, str))


# base64编码
def encode_str(str):
    # 先编码为utf-8字节
    name_bytes = str.encode('utf-8')
    name_base64 = base64.b64encode(name_bytes).decode('utf-8')
    return name_base64


# base64编码
def decode_str(str):
    name_base64 = base64.b64decode(str).decode('utf-8')
    return name_base64
